import { Node, _decorator, Component, instantiate, Label, ProgressBar, v3, Vec3, view, tween, UITransform } from 'cc';
import { EventManager } from './Event/EventManager';
import { GameEventType } from './Event/EnumDefine';
import { DataConfig } from './Config/DataConfig';
import Common from './Config/Common';
const { ccclass, property } = _decorator;

/** 能量条 */
@ccclass('EnergyBar')
export class EnergyBar extends Component {

    @property(ProgressBar) // 绑定 ProgressBar 组件
    progressBar: ProgressBar = null;

    @property(Node)
    xxParent: Node;

    @property(Node) // 光点
    lightDot: Node;

    private totalNum = 100;
    private curNum = 0;

    private progress: number = 0; // 当前进度值
    private targetProgress: number = 0; // 目标进度值
    private speed: number = 1; // 进度条变化速度

    private curEnergyLevel = 0  //当前能量等级

    protected onLoad(): void {
        EventManager.instance.registerEvent(GameEventType.Game_Start, this.onGameStart, this);
        EventManager.instance.registerEvent(GameEventType.Increase_Energy, this.onIncreaseEnergy, this);
        EventManager.instance.registerEvent(GameEventType.Block_Broken, this.onFlyLightDot, this);

        this.onScreen();
        EventManager.instance.registerEvent(GameEventType.Screen_Change, this.onScreen, this);
    }

    start() {
        // 初始化进度条
        this.progressBar.progress = 0;
    }

    onScreen() {
        const visibleSize = view.getVisibleSize();
        this.node.setPosition(v3(0, visibleSize.height / 2 - 100));
    }

    onGameStart() {
        //初始化等级
        this.onResetData(1);
    }

    onResetData(level: number) {
        this.curEnergyLevel = level;
        const configData = DataConfig.energyLevelData;
        if (this.curEnergyLevel <= configData.length) {
            this.totalNum = configData[this.curEnergyLevel - 1].value;
        }
        else {
            //等级超过配置，就取最大等级的数据
            this.totalNum = configData[configData.length - 1].value;
        }
    }

    update(deltaTime: number) {
        if (DataConfig.isGameStop) {
            return;
        }
        let isDropItem = false;
        // 能量条变化
        if (this.progress < this.targetProgress) {
            // 逐渐增加进度
            this.progress += this.speed * deltaTime;
            this.progressBar.progress = this.progress;
            //能量条满了，需要掉落道具
            if (this.progress >= 1) {
                isDropItem = true;
                if (this.curEnergyLevel < DataConfig.energyLevelData.length) {
                    this.curNum = this.curNum - this.totalNum;
                    this.onResetData(this.curEnergyLevel + 1);
                    this.targetProgress = this.curNum / this.totalNum;
                    this.progress = 0
                    this.node.getChildByName("Label").getComponent(Label).string = this.curNum.toString() + "/" + this.totalNum.toString();
                }
            }
        }

        // 星星飞行

        // 掉落道具
        if (isDropItem) {
            EventManager.instance.triggerEvent(GameEventType.Drop_Item, null);
            this.scheduleOnce(() => {
                // 重新提取道具
                EventManager.instance.triggerEvent(GameEventType.Drop_Init, null);
            }, 0.6);
        }
    }

    // 设置目标进度值
    setTargetProgress(target: number) {
        this.targetProgress = target;
    }

    onIncreaseEnergy(value: number) {
        this.curNum += value;
        this.node.getChildByName("Label").getComponent(Label).string = this.curNum.toString() + "/" + this.totalNum.toString();
        if (this.curNum >= this.totalNum) {
            this.targetProgress = 1;
        } else {
            this.targetProgress = this.curNum / this.totalNum;
        }
    }

    /** 数字块破碎时，飞光点到进度条上 */
    onFlyLightDot(params: { pos: Vec3, number: number }) {
        if (DataConfig.isGameStop) {
            return;
        }
        // 使用正确的坐标转换方法
        const randomDis = 200;
        const worldPos = params.pos.clone();
        const startPos = this.node.getComponent(UITransform).convertToNodeSpaceAR(worldPos);
        let getRandomPoint = () => {
            const randomX = startPos.x + Math.floor(Math.random() * randomDis) - randomDis * 0.5;
            const randomY = startPos.y + Math.floor(Math.random() * randomDis) - randomDis * 0.5;
            return v3(randomX, randomY);
        };

        let flyToEnergyBar = (item: Node, iIndex: number, hpToal: number, pStart: Vec3, moveTime: number) => {
            tween(item)
                // 从小变大出现
                .to(0.2, { scale: v3(1, 1, 1) }, {
                    easing: 'backOut'
                })
                // 稍微停顿
                .delay(0.1)
                // 飞向终点并同时缩小
                .to(moveTime, { scale: v3(0.4, 0.4) }, {
                    onUpdate: (target: Node, ratio: number) => {
                        let radio = this.progressBar.progress / 1;
                        radio = radio > 0.95 ? 0.95 : radio;
                        let xStart = -this.progressBar.totalLength * 0.5;
                        let xLength = this.progressBar.totalLength * radio;
                        let pEnd = v3(xStart + xLength, 0);
                        const p0 = v3(pStart.x, pStart.y);
                        const p1 = v3(pEnd.x, pStart.y);
                        const p2 = v3(pEnd.x, pEnd.y);
                        target.position = Common.instance.quadraticBezier(p0, p1, p2, ratio);
                    }
                })
                .call(() => {
                    if (iIndex == 0) {
                        EventManager.instance.triggerEvent(GameEventType.Increase_Energy, hpToal);
                    }
                })
                .call(() => {
                    // 播放终点节点的放大缩小动画
                    // this.playEndNodeAnimation();
                    // 销毁道具节点
                    item.destroy();
                })
                .start();
        };

        let total = params.number > 6 ? 6 : params.number;
        for (let index = 0; index < total; index++) {
            const item = instantiate(this.lightDot);
            item.active = true;
            this.node.addChild(item);
            item.setScale(0, 0);
            item.setPosition(getRandomPoint());
            flyToEnergyBar(item, index, params.number, item.position, 0.5);
        }
    }

    private playEndNodeAnimation() {
        const originalScale = new Vec3(1, 1, 1);
        tween(this.node)
            .set({ scale: originalScale })
            .to(0.05, {
                scale: new Vec3(
                    originalScale.x * 1.1,
                    originalScale.y * 1.1,
                    originalScale.z
                )
            }, {
                easing: 'cubicOut'
            })
            .to(0.05, { scale: originalScale }, {
                easing: 'cubicIn'
            })
            .start();
    }
}
